﻿using System.ComponentModel.DataAnnotations;

namespace DotNetStar.OpenSDK.WeChat.MP
{
    /// <summary>
    /// 生成带参数的二维码。首先创建二维码ticket，然后凭借ticket到指定URL换取二维码。https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1443433542
    /// </summary>
    /// <remarks>
    /// 为了满足用户渠道推广分析和用户帐号绑定等场景的需要，公众平台提供了生成带参数二维码的接口。使用该接口可以获得多个带不同场景值的二维码，用户扫描后，公众号可以接收到事件推送。
    ///目前有2种类型的二维码：
    ///1、临时二维码，是有过期时间的，最长可以设置为在二维码生成后的30天（即2592000秒）后过期，但能够生成较多数量。临时二维码主要用于帐号绑定等不要求二维码永久保存的业务场景
    ///2、永久二维码，是无过期时间的，但数量较少（目前为最多10万个）。永久二维码主要用于适用于帐号绑定、用户来源统计等场景。
    ///用户扫描带场景值二维码时，可能推送以下两种事件：
    ///如果用户还未关注公众号，则用户可以关注公众号，关注后微信会将带场景值关注事件推送给开发者。
    ///如果用户已经关注公众号，在用户扫描后会自动进入会话，微信也会将带场景值扫描事件推送给开发者。
    ///获取带参数的二维码的过程包括两步，首先创建二维码ticket，然后凭借ticket到指定URL换取二维码。
    /// </remarks>
    [HttpPost,ApplicationJson]
    public class QrCodeApiRequest : WeChatMPApiRequest<QrCodeApiResponse>
    {
        /// <summary>
        /// 使用公众号的 access_token 初始化 <see cref="QrCodeApiRequest"/> 类的新实例。
        /// </summary>
        /// <param name="accessToken">公众号的令牌字符串。</param>
        public QrCodeApiRequest(string accessToken) 
            : base($"https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={accessToken}", accessToken)
        {
        }
        /// <summary>
        /// 该二维码有效时间，以秒为单位。 最大不超过2592000（即30天），此字段如果不填，则默认有效期为30秒。
        /// </summary>
        public long Expire_Seconds { get; set; }

        /// <summary>
        /// 二维码类型。
        /// </summary>
        public QrCodeActionNames Action_Name { get; set; } = QrCodeActionNames.QR_SCENE;

        /// <summary>
        /// 表示场景。
        /// </summary>
        public ActionSecen Secen { get; set; }

        /// <summary>
        /// 重写创建参数。
        /// </summary>
        /// <param name="keyValue"><see cref="T:DotNetStar.OpenSDK.KeyValueCollection" /> 实例的动态对象，查看文档了解用法。</param>
        /// <returns>
        /// 默认返回 <see cref="M:DotNetStar.OpenSDK.KeyValueCollection.ToString" /> 方法的结果。在派生类重写时可重新定义一个可以被最终 HTTP 方法识别的返回值。
        /// </returns>
        public override dynamic OnArgumentsCreating(dynamic keyValue)
        {
            keyValue.Clear();//清空所有参数，重新组织参数

            keyValue.Action_Info = this.Secen;
            keyValue.Action_Name = Action_Name.ToString();
            if ((Action_Name == QrCodeActionNames.QR_SCENE || Action_Name == QrCodeActionNames.QR_STR_SCENE) && this.Expire_Seconds != default(long))
            {
                keyValue.expire_seconds = this.Expire_Seconds;
            }

            return SDK.Serialize(keyValue);
        }

        /// <summary>
        /// 表示场景
        /// </summary>
        public class ActionSecen
        {
            /// <summary>
            /// 场景值ID，临时二维码时为32位非0整型，永久二维码时最大值为100000（目前参数只支持1--100000）。自定义编号。
            /// </summary>
            [Range(1, 100000)]
            public int Scene_Id { get; set; }
            /// <summary>
            /// 场景值ID（字符串形式的ID），字符串类型，长度限制为1到64 。自定义字符串。
            /// </summary>
            public string Scene_Str { get; set; }
        }
    }

    /// <summary>
    /// 表示二维码类型的名称。
    /// </summary>
    public enum QrCodeActionNames
    {
        /// <summary>
        /// 临时的整型参数值。
        /// </summary>
        QR_SCENE,
        /// <summary>
        /// 临时的字符串参数值。
        /// </summary>
        QR_STR_SCENE,
        /// <summary>
        /// 永久的整型参数值。
        /// </summary>
        QR_LIMIT_SCENE,
        /// <summary>
        /// 永久的字符串参数值。
        /// </summary>
        QR_LIMIT_STR_SCENE
    }
}
